package com.ganmiao.utils;

import org.apache.commons.lang3.time.DateUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 日期的工具类
 */
public class DateUtil extends DateUtils {
    /**
     * 将日期格式转成指定字符串格式
     *
     * @param date      日期
     * @param strFormat 指定格式
     * @return 返回日期字符串
     */
    public static String formatDate(Date date, String strFormat) {
        String strDate = "";
        SimpleDateFormat sdf = new SimpleDateFormat(strFormat);
        strDate = sdf.format(date);
        return strDate;
    }

    /**
     * 计算日期
     *
     * @param days 若是 要进行推后，则传正数，若是要推算今天之前的 则传负数
     * @return 计算完的最新日期
     */
    public static Date calDate(int days) {
        Date endDate = null;//计算完之后的日期
        //日历对象默认是当前日期
        Calendar calendar = new GregorianCalendar();
        calendar.add(Calendar.DAY_OF_YEAR, days);
        endDate = calendar.getTime();//获得日期当中的日期
        return endDate;

    }

    /**
     * 计算日期
     *
     * @param days 若是 要进行推后，则传正数，若是要推算今天之前的 则传负数
     * @return 计算完的最新日期
     */
    public static Date calDate(Date date, int days) {
        //日历对象默认是当前日期
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_YEAR, days);
        date = calendar.getTime();//获得日期当中的日期
        return date;

    }

    /**
     * 字符串格式转成日期
     *
     * @param stringDate 将要转的字符串
     * @return 转成功后的日期
     */
    public static java.sql.Date dateStr(String stringDate) {
        java.sql.Date date1 = java.sql.Date.valueOf(stringDate);
        return date1;
    }

    public static Date getDate(String stringDate) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date1 = null;
        try {
            date1 = format.parse(stringDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date1;
    }

    /**
     * 获得当前时间戳
     *
     * @return
     */
    public static Long getNowCurrentTimeMillis() {
        return System.currentTimeMillis() / 1000;
    }

    /**
     * 指定日期类型和时间的时间戳
     *
     * @param time    String日期类型
     * @param numTime 额外多加几小时
     * @return
     */
    public static Long currentTimeMillis(String time, int numTime) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = null;
        try {
            date = format.parse(time);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Long timestamp = date.getTime() / 1000 + numTime * 3600;
        return timestamp;
    }

    /**
     * 指定日期的当前日期
     *
     * @param strFormat
     * @return
     */
    public static Date pointNowDate(String strFormat) {
        SimpleDateFormat format = new SimpleDateFormat(strFormat);
        return dateStr(format.format(new Date()));
    }


    /**
     * 转换时间为指定日期格式
     *
     * @param strFormat
     * @return
     */
    public static Date pointDate(Date date, String strFormat) {
        SimpleDateFormat format = new SimpleDateFormat(strFormat);
        return dateStr(format.format(date));
    }

    /**
     * 获得当前时间
     *
     * @return
     */
    public static Date getDate() {
        return new Date();
    }

    /**
     * 切割时间段
     *
     * @param dateType  M/D/H/N ->每月/每天/每小時/每分鐘
     * @param startDate 开始时间（需要目标日期的前一天）
     * @param endDate   结束时间
     * @param format    接收格式
     * @return
     * @throws Exception
     */
    public static List<String> cutDate(String dateType, Date startDate, Date endDate, String format) throws Exception {
        List<String> dateList = new ArrayList<>();
        Calendar calStart = Calendar.getInstance();
        calStart.setTime(startDate);
        Calendar calEnd = Calendar.getInstance();
        calEnd.setTime(endDate);
        while (calEnd.after(calStart)) {
            switch (dateType) {
                case "M":
                    calStart.add(Calendar.MONTH, 1);
                    break;
                case "D":
                    calStart.add(Calendar.DAY_OF_YEAR, 1);
                    break;
                case "H":
                    calStart.add(Calendar.HOUR, 1);
                    break;
                case "N":
                    calStart.add(Calendar.SECOND, 1);
                    break;
            }
            if (calEnd.after(calStart))
                dateList.add(new SimpleDateFormat(format).format(calStart.getTime()));
            else
                dateList.add(new SimpleDateFormat(format).format(calEnd.getTime()));
        }
        return dateList;
    }


    /**
     * days从0开始 0只获取本周第一天
     * 获取本周的日期范围 返回数组类型
     *
     * @param date
     * @return
     */
    public static List<String> getTimeInterval(Date date, int days) {
        List<String> list = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        //判断要计算的日期是否是周日，如果是则减一天计算周六的，否则会出问题，计算到下一周去了
        int dayweek = cal.get(Calendar.DAY_OF_WEEK);//获得当前日期是一个星期的第几天
        if (1 == dayweek) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
        }
        System.out.println("要计算日期为:" + sdf.format(cal.getTime()));
        //输出要计算日期//设置一个屋期的第一天，舷中国的习惯一个星期的第一天是星期一
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        //获得当前目期是一个星期的第几天
        int day = cal.get(Calendar.DAY_OF_WEEK);
        //粮据目历的规剩，给当前目期减去星期几与一个星期第一天的差值
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);
        String startTime = sdf.format(cal.getTime());
        list.add(startTime);

        System.out.println("所在周星期一的目期:" + startTime);
        cal.add(Calendar.DATE, days);
        String endTime = sdf.format(cal.getTime());
        list.add(endTime);
        System.out.println("所在周星期五的目期:" + endTime);

        return list;
    }

    public static Long getDiffDay(Date startTime, Date endTime) {
        Long s = endTime.getTime() - startTime.getTime();
        TimeUnit time = TimeUnit.DAYS;
        return time.convert(s, TimeUnit.MILLISECONDS);
    }

}
